package com.vedana.bankmobile.protobuf.client;

import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;

import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.DefaultHttpClient;

import com.google.protobuf.BlockingRpcChannel;
import com.google.protobuf.Descriptors.MethodDescriptor;
import com.google.protobuf.Message;
import com.google.protobuf.RpcController;
import com.google.protobuf.ServiceException;

/**
 * Blocking (synchronous) HTTP channel for protobuf based RPC.
 * 
 * @author Didier MOISE
 *
 */
public class HttpRpcChannel implements BlockingRpcChannel {
	private String uri;

	final HttpClient client = new DefaultHttpClient();
	
	/**
	 * Constructor
	 * 
	 * @param uri  Server Uri.
	 */
	public HttpRpcChannel(String uri) {
		this.uri = uri;
	}
	
	@Override
	public Message callBlockingMethod(MethodDescriptor method, RpcController controller,
			Message request, Message responsePrototype) throws ServiceException {
        try
        {
          HttpPost post = new HttpPost(uri);
          ByteArrayOutputStream baos = new ByteArrayOutputStream();
          DataOutputStream dos = new DataOutputStream(baos);
          dos.writeInt(method.getIndex());
          dos.writeInt(request.getSerializedSize());
          request.writeTo(dos);
          dos.flush();
          byte[] toSend = baos.toByteArray();
          post.setEntity(new ByteArrayEntity(toSend ));

          HttpResponse response = client.execute(post);
          
          
          DataInputStream dis = new DataInputStream(response.getEntity().getContent());
          
          int size = dis.readInt();
          byte[]array = new byte[size];
          dis.readFully(array);
          return responsePrototype.newBuilderForType().mergeFrom(array).build();
        }
        catch (IOException e)
        {
          throw new ServiceException(e);
        }		
	}
}
